/* Oggetto DataFormatter */

function DataFormatter (catalogURI) {

	// Variabili private

	var currentLayout;
	var currentSkin;
	var supportedSpecials;	// l'array di figli del tag special
	var catalog;
	var listLayout;
	var contentType;

	// Metodi pubblici

	/**
	 * Rinfresca le informazioni provenienti dal catalogo, e chiama quindi le solite funzioni
	 */
	this.refresh = function (callbackWait, callbackOK, callbackError) {
		catalog.refresh (callbackWait,
				function (req) {
					var firstLayout;
					firstLayout = catalog.getFLayouts().getElementsByTagName("layout")[0];
					currentLayout = firstLayout.getAttribute("id");
					currentSkin = firstLayout.getElementsByTagName("skin")[0].getAttribute("id");
					supportedSpecials = catalog.getSpecials();
					listLayout = catalog.getFLayouts ();
					contentType = catalog.getFCType ();
					if (callbackOK)
						callbackOK (req);
				},
				callbackError);
	}

	/**
	 * Modifica i valori di layout e skin
	 * @param {Object} layoutId Id del layout (eventualmente null)
	 * @param {Object} skinId Id della skin (eventualmente null)
	 */
	this.change = function (layoutId, skinId) {
		if (layoutId != null)
			currentLayout = layoutId;
		if (skinId != null)
			currentSkin = skinId;
	}
	
	this.getCurrentLayout = function(){
		return currentLayout;
	}
	
	this.getCurrentSkin = function(){
		return currentSkin;
	}

	this.getLayouts = function () {
		return listLayout;
	}

	this.getContentType = function () {
		return contentType;
	}


	this.formatFragment = function (DOMFormatta, callbackWait, callbackOK, callbackError) {
		format (true, DOMFormatta, callbackWait, callbackOK, callbackError);
	}

	this.formatDocument = function (DOMFormatta, callbackWait, callbackOK, callbackError) {
		format (false, DOMFormatta, callbackWait, callbackOK, callbackError);
	}

	this.getCurrentLayout = function () {
		return currentLayout;
	}

	this.getCurrentSkin = function () {
		return currentSkin;
	}


	// Metodi privati

	/**
	 * Spedisce in POST al formatter la richiesta di formattazione
	 * frammento DOMFormatta, dopo averle impostato il proprio
	 * valore di currentLayout e currentSkin.
	 */
	function format (isFragment, DOMFormatta, callbackWait, callbackOK, callbackError) {

		catalog.refresh (null,
				function (req) {
					var body;
					var url = catalog.getFFrag ();
					if (!isFragment)
						url = catalog.getFDoc ();

					var serializer = new XMLSerializer ();
					var am = new AjaxManager (url, callbackWait, callbackOK, callbackError);

					DOMFormatta.getElementsByTagName ("layout")[0].setAttribute ("id", currentLayout);
					DOMFormatta.getElementsByTagName ("skin")[0].setAttribute ("id", currentSkin);

					body = encodeURIComponent (serializer.serializeToString (DOMFormatta));

					am.post (catalog.getFName() + "=" + body);
				},
				null);

	}
	// Costruttore

	catalog = new CatalogDf (catalogURI);
	this.refresh (null, null, null);

}


/*oggetto formatta creator*/
function FormattaCreator(isFrag){
	//var istanza: array degli ogg dom
	var arrDoms=new Array();
	/*mentre gli specials ci sono sempre questi 3 possono non esserci*/
	var schedaErroreResponse = null;
	var layout;
	var skin;
	
	//metodi: setdom,add,setlayout,setskin
	
	/**
	 * Crea una scheda xml per la richiesta di formatta conforme alle specifiche
	 * @return {Object} Ritorna il DOM così creato 
	 */
	this.getDOM=function(){

		var totDom=createDOM("","");
		var etw="http://ltw.web.cs.unibo.it/esempioErr";
		var p="http://vitali.web.cs.unibo.it/TechWeb08/SCHEMA/tag_speciali";
		var p1="http://www.w3.org/1999/xhtml";
		var p9="http://www.w3.org/1999/xhtml/datatypes/";
		var xsi="http://www.w3.org/2001/XMLSchema-instance";
		var df="http://vitali.web.cs.unibo.it/TechWeb08/SCHEMA/formatta_documento";
		var appStr="formatta_documento formatta_documento.xsd";
		if(isFrag){
			appStr="formatta_frammento formatta_frammento.xsd";
			df="http://vitali.web.cs.unibo.it/TechWeb08/SCHEMA/formatta_frammento";
		}
		var sl="http://vitali.web.cs.unibo.it/TechWeb08/SCHEMA/"+appStr;
		formatta=totDom.createElementNS(df,"df:formatta");
		totDom.appendChild(formatta);
		formatta.setAttribute('xmlns:etw',etw);
		formatta.setAttribute('xmlns:p',p);
		formatta.setAttribute('xmlns:p1',p1);
		formatta.setAttribute('xmlns:p9',p9);
		formatta.setAttribute('xmlns:xsi',xsi);
		formatta.setAttribute('xsi:schemaLocation',sl);
		info=totDom.createElement('info');
		formatta.appendChild(info);
		lay=totDom.createElement('layout');
		info.appendChild(lay);
		lay.setAttribute('id',layout);
		sk=totDom.createElement('skin');
		info.appendChild(sk);
		sk.setAttribute('id',skin);
		dati=totDom.createElement('dati');
		formatta.appendChild(dati);
		if(schedaErroreResponse){
			bodyformatta=totDom.importNode(addDublinCoreOnClicks(schedaErroreResponse).documentElement, true);
			dati.appendChild(bodyformatta);
		}
		if(arrDoms.length!=0){
			spec=totDom.createElement('speciali');
			dati.appendChild(spec);
			for(i=0;i<arrDoms.length;i++){
				justAdded=totDom.importNode(arrDoms[i].documentElement,true);
				spec.appendChild(justAdded);
			}
		}
		return totDom;
	}
	//metto un altra roba nell'array
	this.add = function (toAdd) {
		// Se e' una scheda, un errore o un response li mette al suo
		// posto.
		if (toAdd.getElementsByTagName ("scheda").length != 0
		    || toAdd.getElementsByTagName ("errore").length != 0
		    || toAdd.getElementsByTagName ("response").length != 0)
			schedaErroreResponse = toAdd;
		// Altrimenti e' uno speciale e lo aggiunge all'array degli
		// speciali.
		else
			arrDoms.push(toAdd);
	}
	//aggiorno il layout
	this.setLayout=function(newLay){
		layout=newLay;
	}
	//aggiono la skin
	this.setSkin=function(newSki){
		skin=newSki;
	}
}

/**
 * Aggiunge gli attributi "onclick" agli elementi dublin core, onde farli agire come bottoni und collegamenti
 * @param {Object} DOMSchedaErroreResponse DOM in cui andranno scovati gli elementi dublin core
 */
function addDublinCoreOnClicks (DOMSchedaErroreResponse) {
	var metadati = DOMSchedaErroreResponse.getElementsByTagName("metadati");

	for (var i = 0; i < metadati.length; i++) {
		var eidentifier = metadati[i].getElementsByTagName ("eidentifier")[0].textContent;
		var leaves = DOMSchedaErroreResponse.evaluate ('.//*[count(./*) = 0]', metadati[i], null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE , null); 
		for (var j = 0; j < leaves.snapshotLength; j++) {
			var name = leaves.snapshotItem(j).nodeName;
			var value = leaves.snapshotItem(j).textContent;
			if (name == "eidentifier" || name == "etitle")
				leaves.snapshotItem(j).setAttribute ("onclick", "UILoadScheda ('" + eidentifier + "')");
			else if (name == "erelation")
				leaves.snapshotItem(j).setAttribute ("onclick", "UILoadScheda ('" + value + "')");
			else if (name != "esubject" && name != "edescription") {
				var indiceFarlocco = "";
				if (name == "wcreator" || name == "ecreator" || name == "econtributor" || name == "folksonomia")
					indiceFarlocco = "[0]";
				leaves.snapshotItem(j).setAttribute ("onclick", "UISendQuery ('" + name + indiceFarlocco + "=" + value + "')");
			}
		}
	}
	return DOMSchedaErroreResponse;
}
